/**
 * Copyright (C) 2013-2014 the original author or authors.
 */
package com.foreveross.bsl.mongodb.repository;

import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

import com.mongodb.Mongo;
import com.mongodb.MongoOptions;
import com.mongodb.ServerAddress;

/**
 * @description
 *
 * @author rening
 * @version v1.0
 *
 * @2013-5-31
 *
 */
@Configuration
@Import({MongodbFactoryConfig.class, MongodbTemplateConfig.class})
public class MongodbConfig {
	
	private @Value("${mongo.url}") String mongoUrl;
	
	private @Value("${mongo.defaultDatabase}") String defaultDatabase;
	
	private @Value("${mongo.multiDatabase}") String multiDatabase;
	  
	private @Value("${mongo.username}") String username;
	  
	private @Value("${mongo.password}") String password;
	
	private @Value("${mongo.connections-per-host}") int connectionsPerHost;
	
	private @Value("${mongo.threads-allowed-to-block-for-connection-multiplier}") int threadsAllowedToBlockForConnectionMultiplier;
	
	private @Value("${mongo.connect-timeout}") int connectTimeout;
	
	private @Value("${mongo.max-wait-time}") int maxWaitTime;
	
	private @Value("${mongo.auto-connect-retry}") boolean autoConnectRetry;
	
	private @Value("${mongo.socket-keep-alive}") boolean socketKeepAlive;
	
	private @Value("${mongo.socket-timeout}") int socketTimeout;
	
	private @Value("${mongo.slave-ok}") boolean slaveOk;
	
	private @Value("${mongo.write-number}") int writeNumber;
	
	private @Value("${mongo.write-timeout}") int writeTimeout;
	
	private @Value("${mongo.write-fsync}") boolean writeFsync;
	
	private @Value("${mongo.global-database-package}") String globalDatabasePackage;

	private MongoOptions options=new MongoOptions();
	  
	public @Bean Mongo mongo(){
		
		options.setConnectionsPerHost(connectionsPerHost);
		options.setThreadsAllowedToBlockForConnectionMultiplier(threadsAllowedToBlockForConnectionMultiplier);
		options.setConnectTimeout(connectTimeout);
		options.setMaxWaitTime(maxWaitTime);
		options.setAutoConnectRetry(autoConnectRetry);
		options.setSocketKeepAlive(socketKeepAlive);
		options.setSocketTimeout(socketTimeout);
		options.setWtimeout(writeTimeout);
		options.setFsync(writeFsync);
		
		List<ServerAddress> addrList;
		Mongo mongo=null;
		try {
			if(mongoUrl!=null){
				addrList=new ArrayList<ServerAddress>();
				if(mongoUrl.indexOf(",")!=-1){
					String[] addrs=mongoUrl.split(",");
					for (int i = 0; i < addrs.length; i++) {
						if(addrs[i].indexOf(":")!=-1){
							String[] ipFmat=addrs[i].split(":");
							addrList.add(new ServerAddress(ipFmat[0], Integer.parseInt(ipFmat[1])));
						}else{
							addrList.add(new ServerAddress(addrs[i]));
						}
					}
				} else {
					if(mongoUrl.indexOf(":") != -1){
						String[] ipFmat=mongoUrl.split(":");
						addrList.add(new ServerAddress(ipFmat[0], Integer.parseInt(ipFmat[1])));
					} else {
						addrList.add(new ServerAddress(mongoUrl));
					}
				}
				mongo = new Mongo(addrList, options);
			}else{
				throw new RuntimeException("data access error,host is not null.");
			}
		} catch (NumberFormatException e) {
			throw new RuntimeException(e);
		} catch (UnknownHostException e) {
			throw new RuntimeException(e);
		}
		return mongo;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	/**
	 * @return the options
	 */
	public MongoOptions getOptions() {
		return options;
	}

	/**
	 * @param options the options to set
	 */
	public void setOptions(MongoOptions options) {
		this.options = options;
	}

	/**
	 * @return the defaultDatabase
	 */
	public String getDefaultDatabase() {
		return defaultDatabase;
	}

	/**
	 * @param defaultDatabase the defaultDatabase to set
	 */
	public void setDefaultDatabase(String defaultDatabase) {
		this.defaultDatabase = defaultDatabase;
	}

	/**
	 * @return the multiDatabase
	 */
	public String getMultiDatabase() {
		return multiDatabase;
	}

	/**
	 * @param multiDatabase the multiDatabase to set
	 */
	public void setMultiDatabase(String multiDatabase) {
		this.multiDatabase = multiDatabase;
	}

	/**
	 * @return the globalDatabasePackage
	 */
	public String getGlobalDatabasePackage() {
		return globalDatabasePackage;
	}

	/**
	 * @param globalDatabasePackage the globalDatabasePackage to set
	 */
	public void setGlobalDatabasePackage(String globalDatabasePackage) {
		this.globalDatabasePackage = globalDatabasePackage;
	} 
	
}
